﻿using AutoMapper;
using com.ytocargo.Application.FlightInfos;
using com.ytocargo.Application.FlightInfos.Dto;
using com.ytocargo.Core.AirCraftInfos;
using com.ytocargo.Core.AirPortInfos;
using com.ytocargo.Core.FlightInfo4Monitors;
using com.ytocargo.Core.FlightInfos;
using com.ytocargo.Core.FlightInfoSubs;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yto.Common.Dependency;

namespace com.ytocargo.Application.FlightInfo4Monitors
{
    public class FlightInfo4MonitorServices : IFlightInfo4MonitorServices, ITransient
    {
        private readonly IFlightInfoStore _flightInfoStore;
        private readonly IAirPortInfoStore _airPortInfoStore;
        private readonly IMapper _mapper;
        private IFlightInfo4MonitorStore _flightInfo4MonitorStore;

        private readonly IAirCraftInfoStore _airCraftInfoStore;


        public FlightInfo4MonitorServices(IFlightInfoStore flightInfoStore,
            IAirPortInfoStore airPortInfoStore,
            IMapper mapper,
            IFlightInfo4MonitorStore flightInfo4MonitorStore,
            IAirCraftInfoStore airCraftInfoStore)
        {
            _flightInfoStore = flightInfoStore;
            _airPortInfoStore = airPortInfoStore;
            _mapper = mapper;
            _flightInfo4MonitorStore = flightInfo4MonitorStore;
            _airCraftInfoStore = airCraftInfoStore;
        }

        public List<FlightInfo4Monitor> GetDeleteList()
        {

            var fltInfos = _flightInfoStore.GetAll();
            var flt4Ms = _flightInfo4MonitorStore.GetAll().Where(x => x.FltStatus != "Z"
            && !fltInfos.Select(f => f.Id).Contains(x.FlightId));

            return flt4Ms.ToList();
        }

        public List<FlightInfo4Monitor> GetListByMap(FlightInfoFilter filter)
        {
            var list = new List<FlightInfo4Monitor>();
            var fltInfos = _flightInfoStore.GetAll();
            if (filter != null && filter.FlightDate.HasValue)
            {
                var nextDay = filter.FlightDate.Value.AddDays(1);
                fltInfos = fltInfos.Where(x => x.FlightDate == filter.FlightDate ||
                (x.Etd >= filter.FlightDate && x.Etd < nextDay));
            }
            var airports = _airPortInfoStore.GetAll();
            var airCraftInfos = _airCraftInfoStore.GetAll();
            var result = from a in fltInfos
                         join b in airports on a.DepartureAirPort equals b.Id
                         join c in airports on a.ArrivalAirPort equals c.Id
                         join d in airports on a.FplDivAirport1 equals d.Id into e
                         from f in e.DefaultIfEmpty()
                         join g in airports on a.FplDivAirport2 equals g.Id into h
                         from i in h.DefaultIfEmpty()
                         join j in airCraftInfos on a.AcReg equals j.Id into k
                         from l in k.DefaultIfEmpty()
                         select new
                         {
                             a,
                             b,
                             c,
                             f,
                             i,
                             l
                         };
            result.ToList().ForEach(x =>
            {
                var dto = _mapper.Map<FlightInfoDto>(x.a);
                dto.airPortInfoDep = x.b;
                dto.airPortInfoArr = x.c;
                dto.airPortInfoFpl1 = x.f;
                dto.airPortInfoFpl2 = x.i;
                dto.airCraftInfo = x.l;
                var fltInfo4M = _mapper.Map<FlightInfo4Monitor>(dto);
                fltInfo4M.FlightInfoSub = _mapper.Map<FlightInfoSub>(dto);
                list.Add(fltInfo4M);
            });
            return list;
        }

        public async Task<bool> QueryByEntity(FlightInfo4Monitor flightInfo4Monitor)
        {
            bool IsExsit = false;
            var entity = await _flightInfo4MonitorStore.FirstOrDefaultAsync(x =>

                x.FlightId == flightInfo4Monitor.FlightId
                && x.FltId == flightInfo4Monitor.FltId
                && x.FltIdFix == flightInfo4Monitor.FltIdFix
                && x.FltSeq == flightInfo4Monitor.FltSeq
                && x.FltDate == flightInfo4Monitor.FltDate
                && x.CoSeq == flightInfo4Monitor.CoSeq
                && x.FltTask == flightInfo4Monitor.FltTask
                && x.ServiceType == flightInfo4Monitor.ServiceType
                && x.FltType == flightInfo4Monitor.FltType
                && x.FltOpType == flightInfo4Monitor.FltOpType
                && x.FltStatus == flightInfo4Monitor.FltStatus
                && x.ConFltId == flightInfo4Monitor.ConFltId
                && x.ConFltIdFix == flightInfo4Monitor.ConFltIdFix
                && x.ConCompanyCode2 == flightInfo4Monitor.ConCompanyCode2
                && x.ConFltDate == flightInfo4Monitor.ConFltDate
                && x.FltLoopId == flightInfo4Monitor.FltLoopId
                && x.Std == flightInfo4Monitor.Std
                && x.Sta == flightInfo4Monitor.Sta
                && x.SchDepApt == flightInfo4Monitor.SchDepApt
                && x.SchArrApt == flightInfo4Monitor.SchArrApt
                && x.Etd == flightInfo4Monitor.Etd
                && x.Eta == flightInfo4Monitor.Eta
                && x.DepApt == flightInfo4Monitor.DepApt
                && x.ArrApt == flightInfo4Monitor.ArrApt
                && x.LatestOffTime == flightInfo4Monitor.LatestOffTime
                && x.LatestOnTime == flightInfo4Monitor.LatestOnTime
                && x.LatestOffStatus == flightInfo4Monitor.LatestOffStatus
                && x.LatestOnStatus == flightInfo4Monitor.LatestOnStatus
                && x.DoorCloseTime == flightInfo4Monitor.DoorCloseTime
                && x.OffBlockTime == flightInfo4Monitor.OffBlockTime
                && x.OutTime == flightInfo4Monitor.OutTime
                && x.TaxioutTime == flightInfo4Monitor.TaxioutTime
                && x.OffTime == flightInfo4Monitor.OffTime
                && x.OnTime == flightInfo4Monitor.OnTime
                && x.TaxiinTime == flightInfo4Monitor.TaxiinTime
                && x.InTime == flightInfo4Monitor.InTime
                && x.OnBlockTime == flightInfo4Monitor.OnBlockTime
                && x.DoorsOpnTime == flightInfo4Monitor.DoorsOpnTime
                && x.StdSrc == flightInfo4Monitor.StdSrc
                && x.StaSrc == flightInfo4Monitor.StaSrc
                && x.EtdSrc == flightInfo4Monitor.EtdSrc
                && x.EtaSrc == flightInfo4Monitor.EtaSrc
                && x.LatestOffTimeSrc == flightInfo4Monitor.LatestOffTimeSrc
                && x.LatestOnTimeSrc == flightInfo4Monitor.LatestOnTimeSrc
                && x.LatestOffStatusSrc == flightInfo4Monitor.LatestOffStatusSrc
                && x.LatestOnStatusSrc == flightInfo4Monitor.LatestOnStatusSrc
                && x.DoorCloseTimeSrc == flightInfo4Monitor.DoorCloseTimeSrc
                && x.OffBlockTimeSrc == flightInfo4Monitor.OffBlockTimeSrc
                && x.OutTimeSrc == flightInfo4Monitor.OutTimeSrc
                && x.TaxioutTimeSrc == flightInfo4Monitor.TaxioutTimeSrc
                && x.OffTimeSrc == flightInfo4Monitor.OffTimeSrc
                && x.OnTimeSrc == flightInfo4Monitor.OnTimeSrc
                && x.TaxiinTimeSrc == flightInfo4Monitor.TaxiinTimeSrc
                && x.InTimeSrc == flightInfo4Monitor.InTimeSrc
                && x.OnBlockTimeSrc == flightInfo4Monitor.OnBlockTimeSrc
                && x.DoorsOpnTimeSrc == flightInfo4Monitor.DoorsOpnTimeSrc
                && x.LatestUpdateSrc == flightInfo4Monitor.LatestUpdateSrc
                && x.DealTime == flightInfo4Monitor.DealTime
                && x.FltIdAltn == flightInfo4Monitor.FltIdAltn
                && x.FltSeqReal == flightInfo4Monitor.FltSeqReal
                && x.FltIdPk == flightInfo4Monitor.FltIdPk
                && x.StartCheckTime == flightInfo4Monitor.StartCheckTime
                && x.StdLocal == flightInfo4Monitor.StdLocal
                && x.StaLocal == flightInfo4Monitor.StaLocal
                && x.EtdLocal == flightInfo4Monitor.EtdLocal
                && x.EtaLocal == flightInfo4Monitor.EtaLocal
                && x.DoorCloseTimeLocal == flightInfo4Monitor.DoorCloseTimeLocal
                && x.OffBlockTimeLocal == flightInfo4Monitor.OffBlockTimeLocal
                && x.OutTimeLocal == flightInfo4Monitor.OutTimeLocal
                && x.TaxioutTimeLocal == flightInfo4Monitor.TaxioutTimeLocal
                && x.OffTimeLocal == flightInfo4Monitor.OffTimeLocal
                && x.OnTimeLocal == flightInfo4Monitor.OnTimeLocal
                && x.TaxiinTimeLocal == flightInfo4Monitor.TaxiinTimeLocal
                && x.InTimeLocal == flightInfo4Monitor.InTimeLocal
                && x.OnBlockTimeLocal == flightInfo4Monitor.OnBlockTimeLocal
                && x.DoorsOpnTimeLocal == flightInfo4Monitor.DoorsOpnTimeLocal
                && x.SoflSeqNr == flightInfo4Monitor.SoflSeqNr
                //&& x.FltDatePek == flightInfo4Monitor.FltDatePek
                && x.ChangeTime == flightInfo4Monitor.ChangeTime
                //&& x.CargoDoorCloseTime == flightInfo4Monitor.CargoDoorCloseTime
                && x.CargoDoorCloseTimeLocal == flightInfo4Monitor.CargoDoorCloseTimeLocal
                //&& x.CabinDoorCloseTime == flightInfo4Monitor.CabinDoorCloseTime
                //&& x.CabinDoorCloseTimeLocal == flightInfo4Monitor.CabinDoorCloseTimeLocal
                && x.GlobalPk == flightInfo4Monitor.GlobalPk
            );
            if (entity != null)
            {
                IsExsit = true;
            }
            return IsExsit;
        }

        public async Task UpdateOrInsert(FlightInfo4Monitor flightInfo4Monitor)
        {

            var entity = await _flightInfo4MonitorStore.FirstOrDefaultAsync(x => x.FlightId == flightInfo4Monitor.FlightId);
            if (entity != null)
            {
                _flightInfo4MonitorStore.Detach(entity);
                flightInfo4Monitor.Id = entity.Id;
                await _flightInfo4MonitorStore.UpdateAsync(flightInfo4Monitor);
            }
            else
            {
                await _flightInfo4MonitorStore.InsertAsync(flightInfo4Monitor);
            }
        }
    }
}
